#ifndef _UTILS_H_
#define _UTILS_H_

/**
*	@打印调试宏
*	@如果需要打开所有打印信息,定义DEBUG_ALL,当只需要某些模块打印,在每个模块定义DEBUG
*/
#if defined(DEBUG) || defined(DEBUG_ALL)
	#define TRACE(x,args...) do{fprintf (stderr, "[%s/%s ()/L%d] "x, __FILE__, __FUNCTION__, __LINE__, ##args) ;}while(0)
	#define PRINTF(x,args...) do{ printf(x,##args); }while(0)
	#define TRACE_HEX(buf,size) do{\
		int i=0,j=0,k=0;\
		printf("________[%s/%s()/L%d/size:%d]________\n", __FILE__, __FUNCTION__, __LINE__,size);\
		for(i=0;i< (((size)%16 == 0)? (int)(size)/16:((int)(size)/16+1)) ;i++)\
		{\
			k=(i==((int)(size)/16))?((int)size%16):16;\
			for(j=0;j<k;j++){ printf("%02x ",(uint32)(buf)[16*i+j]&0xFF); }	\
			if( i==((int)size/16) ){ for(j=0;j<(16-(size)%16)*3;j++) printf(" ");}\
			printf(" ;  ");\
			for(j=0;j<k;j++){ printf("%c",(int)((buf)[16*i+j]&0xFF));}		printf("\n");\
		}\
		printf("==========4=[buffer pri nt end]==12=============\n");\
	}while(0)		
#else
	#define TRACE(x,args...)
	#define PRINTF(x,args...)
	#define TRACE_HEX(buf,size)
#endif

/**
*	@取大数或小数宏,使用MIN或MAX宏需要注意其限制和副作用
*	@min或max具有宏内++,--安全,但函数作为参数,函数会执行两次.(void) (&_x == &_y);比较类型,类型不一致,编译器会出警告
*	@typeof是gcc扩展关键字(返回参数类型),不通用,可能c++中采用内联函数加模板才是最通用的做法
*/
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a>b)?(a):(b))
#define min(x,y) ({ \
	typeof(x) _x = (x);	\
	typeof(y) _y = (y);	\
	(void) (&_x == &_y);\
	_x < _y ? _x : _y; })
#define max(x,y) ({ \
	typeof(x) _x = (x);	\
	typeof(y) _y = (y);	\
	(void) (&_x == &_y);\
	_x > _y ? _x : _y; })




#endif //_UTILS_H_
